/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package model.session;

import java.util.Date;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpSession;
import logic.AccountCreatorLocal;
import logic.CustomerManagerLocal;
import persistence.AuthenticationInfo;
import persistence.IdentityInfo;
import persistence.MemberType;


/**
 *
 * sert de façade à la logique métier pour la gestion des comptes
 * Un découpage des responsabilités plus poussé et donc modulaire aurait pu être mise en place.
 * Mais aprés 2 jours de théorie / pratique ce type de découpage est acceptable
 */
@ManagedBean(name="memberModel")
@SessionScoped
public class MemberBean {
    //injection des sessions beans
    @EJB
    private CustomerManagerLocal customerManagerBean;//SLSB
    @EJB
    private AccountCreatorLocal accountCreator;//SFSB


    //propriétés du modèle assignées durant la phase update model value
    private Long id;
    private String firstname;
    private String lastname;
    private String login;
    private UIInput password;//propriété liée au composant UIInput d'id pass1id
    private UIInput password2;
    private Date dob;
    private MemberType memberType;


    /** Creates a new instance of MemberBean */
    public MemberBean() {
      
    }



 //méthodes d'action : retourne une référence de type String pour la navigation - pas d'argument
 //méthodes s'exécutant durant la phase invoke application
    public String authenticate(){
    String pwd = (String) password.getValue();
     boolean exists = customerManagerBean.memberExists(login, pwd);
     if(!exists){
        
       closeSession();//clôture de la session http sous-jacente
        return "failed";
     }else {
         FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Auth_", "authorized");
         return "logged";
     }
    }

    //se déconnecter
    public String logout(){
        closeSession();
        return "logout";
    }

    //annuler la création de compte
    public String cancelAccountCreation(){
        accountCreator.cancelAccount();//on clôt le dialogue. les SFSB sera supprimé de la mémoire
        closeSession();//on clôture la session en cours
        return "cancel";
    }

    //enregistrer le compte
    public String register(){

      if(customerManagerBean.retrieveMemberByLogin(login)!=null){
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "veuillez choisir un autre identifiant", null);
            FacesContext ctx= FacesContext.getCurrentInstance();//on récupère le contexte de la requête en cours
            ctx.addMessage(null, message);//on place le message dans la queue des messages
            return null;
        }
        AuthenticationInfo ai =new AuthenticationInfo();
        ai.setLogin(login);
        ai.setPwd((String) password.getValue());
        ai.setType(memberType);
            accountCreator.addAuthenticationInfo(ai);

        IdentityInfo ii =new IdentityInfo();
        ii.setFirstname(firstname);
        ii.setLastname(lastname);
        ii.setDob(dob);
            accountCreator.addIdentityInfo(ii);

       accountCreator.createAccount();//l'instance SFSB est détruite.
       //Il faudrait gérer l'éventuel échec de la création de compte

       //On clôture la session d'inscription
       closeSession();

       return "registered";
    }

   //méthode pour valider la double saisie du mot de passe. type de validation personnalisée le plus sipmle.
    //on peut aussi utiliser un validateur personnalisé (cf. validators.PasswordValidator).
    public void validatePassword(FacesContext ctx, UIComponent toValidate, Object value)throws ValidatorException{
      String pwd2= (String)value;
      String pwd =(String) password.getValue();//la valeur value de cette propriété liée aux composant est assignée durant la phase apply request value
      
         if (!pwd2.equals(pwd)){
             FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "vous n'avez pas saisi le même mdp", null);
             throw new ValidatorException(message);
         }
    }

//accesseurs et mutateurs pour les propriétés répondant aux conventions javabeans
//les setters assignent la valeurs des composants liés aux propriétés durant la phase update model values

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public MemberType getMemberType() {
        return memberType;
    }

    public void setMemberType(MemberType memberType) {
        this.memberType = memberType;
    }

    public UIInput getPassword() {
        return password;
    }

    public void setPassword(UIInput password) {
        this.password = password;
    }

    public UIInput getPassword2() {
        return password2;
    }

    public void setPassword2(UIInput password2) {
        this.password2 = password2;
    }


    private void closeSession(){
       // on récupère la session http et on l'invalide - utilisation de FacesContext
         HttpSession currentSession=(HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
       currentSession.invalidate();
    }
}
